﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net;
using System.Windows.Forms;
using System.IO;
using System.IO.Compression;
using Newtonsoft.Json;
using System.Drawing;
using HtmlAgilityPack;

namespace AutoBuyWinform
{
    class Util
    {
        public static bool isEmpty(string str)
        {
            if (str == null || "".Equals(str.Trim()))
                return true;
            else
                return false;
        }

        //用于获取验证码图像的方法
        public static Stream GetCheckCodeImageStream(string imageAddress, CookieContainer ccEntered, out CookieCollection ccReturned)
        {
            HttpWebRequest request;
            HttpWebResponse response;

            request = (HttpWebRequest)HttpWebRequest.Create(imageAddress);

            request.Method = "GET";
            request.ProtocolVersion = HttpVersion.Version11;
            //request.Connection = "keep-alive";
            request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.861.0 Safari/535.2";
            request.Accept = "*/*";

            //request.Connection = "keep-alive";
            request.KeepAlive = true;
            //request.Headers.Add("Connection", "keep-alive"); 

            request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
            request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
            request.Headers.Add("Accept-Charset", "GBK,utf-8;q=0.7,*;q=0.3");

            request.CookieContainer = ccEntered;

            request.AllowAutoRedirect = true;

            response = (HttpWebResponse)request.GetResponse();
            ccReturned = response.Cookies;

            return response.GetResponseStream();
        }

        //用于获取商品页面的方法
        public static string GetPage(string pageUrl, CookieContainer ccEntered, out CookieCollection ccReturned)
        {
            HttpWebRequest request;
            HttpWebResponse response;

            request = (HttpWebRequest)HttpWebRequest.Create(pageUrl);

            request.Method = "GET";
            request.ProtocolVersion = HttpVersion.Version11;
            //request.Connection = "keep-alive";
            request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.861.0 Safari/535.2";
            request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";

            //request.Connection = "keep-alive";
            request.KeepAlive = true;
            //request.Headers.Add("Connection", "keep-alive"); 

            request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
            request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
            request.Headers.Add("Accept-Charset", "GBK,utf-8;q=0.7,*;q=0.3");

            request.CookieContainer = ccEntered;

            request.AllowAutoRedirect = true;

            response = (HttpWebResponse)request.GetResponse();
            ccReturned = response.Cookies;

            ////show cookie
            //StringBuilder sb = new StringBuilder();
            //foreach (Cookie cookieValue in request.CookieContainer.GetCookies(new Uri(Form1.webUrl)))
            //{
            //    sb.AppendLine("Cookie: " + cookieValue.ToString());
            //}
            //MessageBox.Show(sb.ToString());

            Stream st;
            st = response.GetResponseStream();

            if (response.ContentEncoding.ToLower().Contains("gzip"))
            {
                st = new GZipStream(st, CompressionMode.Decompress, true);
            }

            string htmlText;

            StreamReader stReader = new StreamReader(st, Encoding.UTF8);
            htmlText = stReader.ReadToEnd();

            stReader.Close();
            st.Close();

            response.Close();

            return htmlText;
        }



    }

    public class RespStatus
    {
        public int status { get; set; }
        public string message { get; set; }
        public string forwardUrl { get; set; }
    }

    public class Product
    {
        public long packId {get;set;}
        public double weight {get;set;}
        public string price { get; set; }
        public string productTypeId {get;set;}
        public string prodTypeDesc {get;set;}
        public string providerCode { get; set; }
        public int[] yj = new int[3];
    };

    public class PostGoodsToCart
    {
        private Product product;
        private int waitTime;
        private CookieContainer cc;
        private CookieCollection ccReturned;
        private CheckCodeForm checkCodeForm;
        //private Logs logs;


        public PostGoodsToCart(Product product, CookieContainer ccEntered)
        {
            this.product = product;
            this.waitTime = Form1.waitTime;
            this.cc = ccEntered;
            //this.logs = new Logs(true);
            //this.logs.setLogFormTitle(product.prodTypeDesc);
            //this.logs.ShowForm();
            this.checkCodeForm = new CheckCodeForm();
        }

        public bool doPost(LogForm logForm)
        {
            bool success = false;
            DateTime time1 = DateTime.Now;

            while (!success && (DateTime.Now-time1).TotalMilliseconds<Form1.timeLength*60*1000)
            {
                Thread.Sleep(waitTime);
                success = PostToCart(logForm);
            }

            cc.Add(ccReturned);

            return success;
        }

        //加入购物车
        public bool PostToCart(LogForm logForm)
        {
            HttpWebRequest request = null;
            HttpWebResponse response = null;
            bool success = false;
            string csrftoken = "";
            string htmlText;

            request = (HttpWebRequest)HttpWebRequest.Create(Form1.postToCartUrl);
            request.CookieContainer = new CookieContainer();

            string data = "provider_code=" + product.providerCode + "&packId=" + product.packId;

            byte[] postData = Encoding.UTF8.GetBytes(data);

            //赋值权限戳
            foreach (Cookie cookieValue in cc.GetCookies(new Uri(Form1.webUrl)))
            {
                if ("csrftoken".Equals(cookieValue.Name))
                {
                    csrftoken = cookieValue.Value;
                }
            }

            request.Method = "POST";
            request.ProtocolVersion = HttpVersion.Version11;

            //request.Connection = "keep-alive";

            request.UserAgent = "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31";
            request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
            request.ContentLength = postData.Length;
            request.Referer = Form1.webUrl;
            request.Accept = "application/json, text/javascript, */*; q=0.01";

            request.KeepAlive = true;
            //request.Headers.Add("Connection", "keep-alive");

            request.Headers.Add("Origin", Form1.goodsUrl);
            request.Headers.Add("Cache-Control", "max-age=0");
            request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
            request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
            request.Headers.Add("Accept-Charset", "GBK,utf-8;q=0.7,*;q=0.3");
            request.Headers.Add("X-Requested-With", "XMLHttpRequest");
            request.Headers.Add("X-CSRFToken", csrftoken);

            request.CookieContainer = cc;

            Stream st = request.GetRequestStream();
            st.Write(postData, 0, postData.Length);
            st.Close();

            request.AllowAutoRedirect = false;

            try
            {
                response = (HttpWebResponse)request.GetResponse();
                ccReturned = response.Cookies;

                Stream st2 = response.GetResponseStream();

                if (response.ContentEncoding.ToLower().Contains("gzip"))
                {
                    st = new GZipStream(st2, CompressionMode.Decompress, true);
                }

                

                StreamReader stReader = new StreamReader(st2, Encoding.Default);
                htmlText = stReader.ReadToEnd();

                stReader.Close();
                st2.Close();

                response.Close();
            }
            catch (Exception)
            {
                ccReturned = null;
                if (response != null)
                {
                    response.Close();
                }
                return false;
            }
            
            RespStatus rs = JsonConvert.DeserializeObject<RespStatus>(htmlText);

            if (rs.status == 1)
            {
                // 添加成功
                logForm.Invoke(new Action(() =>
                {
                    logForm.setMsg("加入购物车成功");
                }));
                success = true;
            } else if (rs.status == 0) {
                // 业务失败
                logForm.Invoke(new Action(() =>
                {
                    logForm.setMsg("业务失败");
                }));
            } else if (rs.status == -2) {
                // 需要重新登录
                logForm.Invoke(new Action(() =>
                {
                    logForm.setMsg("需要重新登录");
                }));
            } else if (rs.status == 2) {
                // 该资源已在购物车
                logForm.Invoke(new Action(() =>
                {
                    logForm.setMsg("该资源已在购物车");
                }));
                success = true;
            } else if (rs.status == -20) {
                //showMessageDialog('未到开盘时间.');
                logForm.Invoke(new Action(() =>
                {
                    logForm.setMsg("未到开盘时间");
                }));
            } else {
                // 其他错误
                logForm.Invoke(new Action(() =>
                {
                    logForm.setMsg(rs.message);
                }));
            }

            return success;
        }

        public HttpWebRequest createRequest(string targetUrl, string data, string originUrl, string refererUrl, string method, string acceptType)
        {
            string csrftoken = "";
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(targetUrl);
            request.CookieContainer = new CookieContainer();

            byte[] postData = Encoding.UTF8.GetBytes(data);

            //赋值权限戳
            foreach (Cookie cookieValue in cc.GetCookies(new Uri(Form1.webUrl)))
            {
                if ("csrftoken".Equals(cookieValue.Name))
                {
                    csrftoken = cookieValue.Value;
                }
                if ("sessionid".Equals(cookieValue.Name))
                {
                    //MessageBox.Show(cookieValue.Value);
                }
            }

            request.Method = method;
            request.ProtocolVersion = HttpVersion.Version11;


            request.UserAgent = "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31";
            request.Referer = refererUrl;
            //request.KeepAlive = true;
            var sp = request.ServicePoint;
            var prop = sp.GetType().GetProperty("HttpBehaviour", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            prop.SetValue(sp, (byte)0, null);

            request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
            request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
            request.Headers.Add("Accept-Charset", "GBK,utf-8;q=0.7,*;q=0.3");
            //request.Headers.Add("Cache-Control", "max-age=0");

            request.CookieContainer = cc;

            if ("POST".Equals(method))
            {
                request.Accept = acceptType;
                request.ContentLength = postData.Length;
                request.Headers.Add("Origin", originUrl);
                request.Headers.Add("X-CSRFToken", csrftoken);
                request.Headers.Add("X-Requested-With", "XMLHttpRequest");
                request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
            }
            else
            {
                request.Accept = acceptType;
            }
            
            

            if ("POST".Equals(method))
            {
                Stream st = request.GetRequestStream();
                st.Write(postData, 0, postData.Length);
                st.Close();
            }

            request.AllowAutoRedirect = false;
            return request;
        }

        public String getResponse(HttpWebRequest request)
        {
            HttpWebResponse response = null;
            string htmlText = null;
            try
            {
                response = (HttpWebResponse)request.GetResponse();
                ccReturned = response.Cookies;


                Stream st2 = response.GetResponseStream();

                if (response.ContentEncoding.ToLower().Contains("gzip"))
                {
                    st2 = new GZipStream(st2, CompressionMode.Decompress, true);
                }



                StreamReader stReader = new StreamReader(st2, Encoding.UTF8);
                htmlText = stReader.ReadToEnd();

                stReader.Close();
                st2.Close();

                response.Close();
            }
            catch (Exception)
            {
                ccReturned = null;
                if (response != null)
                {
                    response.Close();
                }
                return null;
            }

            return htmlText;
        }

        /// <summary>
        /// 直接生成订单
        /// </summary>
        /// <param name="logForm"></param>
        /// <returns></returns>
        public bool createOrder(LogForm logForm)
        {
            HttpWebRequest request = null;
            bool success = false;
            string veriCode = "";
            string htmlText;

            //veriCode = GetVeriCode(Form1.captchaUrl);
            //if (Util.isEmpty(veriCode))
            //{
            //    return false;
            //}

            string data = "pack_ids=" + product.packId + "&provider_code=" + product.providerCode + "&captcha=" + veriCode;
            request = createRequest(Form1.createOrderUrl, data, Form1.goodsUrl, Form1.goodsUrl, "POST", Constants.ACCEPT_TYPE_JSON);

            //request = (HttpWebRequest)HttpWebRequest.Create(Form1.createOrderUrl);
            //request.CookieContainer = new CookieContainer();

            //string data = "pack_ids=" + product.packId + "&provider_code=" + product.providerCode + "&captcha=" + veriCode;

            //byte[] postData = Encoding.UTF8.GetBytes(data);

            ////赋值权限戳
            //foreach (Cookie cookieValue in cc.GetCookies(new Uri(Form1.webUrl)))
            //{
            //    if ("csrftoken".Equals(cookieValue.Name))
            //    {
            //        csrftoken = cookieValue.Value;
            //    }
            //}

            //request.Method = "POST";
            //request.ProtocolVersion = HttpVersion.Version11;

            ////request.Connection = "keep-alive";

            //request.UserAgent = "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31";
            //request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
            //request.ContentLength = postData.Length;
            //request.Referer = Form1.webUrl;
            //request.Accept = "application/json, text/javascript, */*; q=0.01";

            //request.KeepAlive = true;
            ////request.Headers.Add("Connection", "keep-alive");

            //request.Headers.Add("Origin", Form1.goodsUrl);
            //request.Headers.Add("Cache-Control", "max-age=0");
            //request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
            //request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
            //request.Headers.Add("Accept-Charset", "GBK,utf-8;q=0.7,*;q=0.3");
            //request.Headers.Add("X-Requested-With", "XMLHttpRequest");
            //request.Headers.Add("X-CSRFToken", csrftoken);

            //request.CookieContainer = cc;

            //Stream st = request.GetRequestStream();
            //st.Write(postData, 0, postData.Length);
            //st.Close();

            //request.AllowAutoRedirect = false;

            //try
            //{
            //    response = (HttpWebResponse)request.GetResponse();
            //    ccReturned = response.Cookies;


            //    Stream st2 = response.GetResponseStream();

            //    if (response.ContentEncoding.ToLower().Contains("gzip"))
            //    {
            //        st = new GZipStream(st2, CompressionMode.Decompress, true);
            //    }

                

            //    StreamReader stReader = new StreamReader(st2, Encoding.Default);
            //    htmlText = stReader.ReadToEnd();

            //    stReader.Close();
            //    st2.Close();

            //    response.Close();
            //}
            //catch (Exception)
            //{
            //    ccReturned = null;
            //    if (response != null)
            //    {
            //        response.Close();
            //    }
            //    return false;
            //}

            htmlText = getResponse(request);
            RespStatus rs = JsonConvert.DeserializeObject<RespStatus>(htmlText);

            if (rs.status == 1)
            {
                // 添加成功
                logForm.Invoke(new Action(() =>
                {
                    logForm.setMsg("直接生成订单成功！");
                }));
                success = true;
            }
            else if (rs.status == -20)
            {
                // 未到开盘时间，不能生成合同。
                logForm.Invoke(new Action(() =>
                {
                    logForm.setMsg("未到开盘时间，不能生成合同");
                }));
            }
            else if (rs.status == -2)
            {
                // 需要重新登录
                logForm.Invoke(new Action(() =>
                {
                    logForm.setMsg("需要重新登录");
                }));
            }
            else if (rs.status == -3)
            {
                // show message
                logForm.Invoke(new Action(() =>
                {
                    logForm.setMsg(rs.message);
                }));
            }
            else
            {
                // show message, 请返回重新操作。
                logForm.Invoke(new Action(() =>
                {
                    logForm.setMsg(rs.message + ", 请返回重新操作");
                }));
            }

            return success;
        }

        

        /// <summary>
        /// 议价生成订单
        /// 打开议价页面
        /// </summary>
        /// <param name="logForm"></param>
        /// <returns></returns>
        public bool createYj(LogForm logForm,YjPage yjPage)
        {
            HttpWebRequest request = null;
            bool success = false;
            string htmlText;

            //点击议价按钮
            string data = "pack_ids=" + product.packId + "&provider_code=" + product.providerCode + "&price_sum=" + product.weight * float.Parse(product.price);
            request = createRequest(Form1.yjPageUrl, data, Form1.goodsUrl, Form1.goodsUrl, "POST", Constants.ACCEPT_TYPE_JSON);

            //获取议价跳转链接
            htmlText = getResponse(request);
            RespStatus rs = JsonConvert.DeserializeObject<RespStatus>(htmlText);

            if (rs.status == 1)
            {
                foreach (Cookie cookieValue in cc.GetCookies(new Uri(Form1.webUrl)))
                {
                    yjPage.addCookie(cookieValue);
                }
                yjPage.resetUrl(rs.forwardUrl);
                yjPage.resetTitle(rs.forwardUrl);
                yjPage.Visible = true;
                request = createRequest(rs.forwardUrl, "", Form1.cartUrl, Form1.goodsUrl, "GET", Constants.ACCEPT_TYPE_XML);
                htmlText = getResponse(request);

                //打开议价对话框
                string chatUrl = Form1.chatUrl + htmlText.Substring(htmlText.IndexOf('\'', 0) + 1, htmlText.IndexOf('\'', htmlText.IndexOf('\'', 0) + 1) - htmlText.IndexOf('\'', 0) - 1);
                request = createRequest(chatUrl, "", Form1.cartUrl, Form1.goodsUrl, "GET", Constants.ACCEPT_TYPE_XML);
                htmlText = getResponse(request);

                //解析议价窗口
                // 使用預設編碼讀入 HTML
                HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                doc.LoadHtml(htmlText);
                // 裝載Chat body
                HtmlAgilityPack.HtmlDocument chatBodyContext = new HtmlAgilityPack.HtmlDocument();

                chatBodyContext.LoadHtml(doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[1]/div[1]/div[1]").InnerHtml);

                //获取参数
                String sycsStr = chatBodyContext.DocumentNode.SelectSingleNode("./div[1]/div[2]/span[1]").InnerText;
                int sycs=0;//剩余次数
                if (sycsStr != null && !"".Equals(sycsStr))
                {
                    sycs = Int32.Parse(sycsStr);
                }
                String csrfmiddlewaretoken = chatBodyContext.DocumentNode.SelectSingleNode("./div[3]/div[1]/input[1]").GetAttributeValue("value", null);
                String nick_name = chatBodyContext.DocumentNode.SelectSingleNode("./div[3]/input[1]").GetAttributeValue("value", null);
                String group_num = chatBodyContext.DocumentNode.SelectSingleNode("./div[3]/input[2]").GetAttributeValue("value", null);
                String agent_type = chatBodyContext.DocumentNode.SelectSingleNode("./div[3]/input[3]").GetAttributeValue("value", null);

                //如果可以议价，则进行议价
                if (group_num != null && !"".Equals(group_num) && !"0".Equals(group_num))
                {
                    // show message, 请返回重新操作。
                    logForm.Invoke(new Action(() =>
                    {
                        logForm.setMsg("还有" + sycs+"次议价机会");
                    }));
                    success = doYj(logForm, csrfmiddlewaretoken, nick_name, group_num, agent_type, sycs, chatUrl);
                }
                else
                {
                    // 不能进行议价。
                    logForm.Invoke(new Action(() =>
                    {
                        logForm.setMsg("不能进行议价");
                    }));
                }
                
            }
            else if (rs.status == -20)
            {
                // 未到开盘时间，不能生成合同。
                logForm.Invoke(new Action(() =>
                {
                    logForm.setMsg("未到开盘时间或账户异常,不能操作购物车");
                }));
            }
            else
            {
                // show message, 请返回重新操作。
                logForm.Invoke(new Action(() =>
                {
                    logForm.setMsg(rs.message);
                }));
            }

            return success;
        }


        /// <summary>
        /// 议价生成订单
        /// 进行议价
        /// </summary>
        /// <param name="logForm"></param>
        /// <returns></returns>
        public bool doYj(LogForm logForm, String csrfmiddlewaretoken, String nick_name, String group_num, String agent_type, int sycs, string chatUrl)
        {
            HttpWebRequest request = null;
            bool success = false;
            string htmlText;

            //获取议价信息

            string data1 = "csrfmiddlewaretoken=" + csrfmiddlewaretoken;
            request = createRequest(Form1.yjUpdateMsgUrl, data1, Form1.chatUrl, chatUrl, "POST", Constants.ACCEPT_TYPE_PLAIN);
            htmlText = getResponse(request);

            //点击议价按钮
            string data2 = "csrfmiddlewaretoken=" + csrfmiddlewaretoken + "&nick_name=" + nick_name + "&group_num=" + group_num + "&agent_type=" + agent_type;

            for (int i = 0; i < sycs; i++)
            {
                request = createRequest(Form1.yjSendMsgUrl, data2+"&pre_price=" + product.yj[i], Form1.goodsUrl,Form1.goodsUrl, "POST", Constants.ACCEPT_TYPE_PLAIN);

                //获取议价跳转链接
                htmlText = getResponse(request);
                if (htmlText != null && !"".Equals(htmlText) && !"[]".Equals(htmlText))
                {
                    RespStatus rs = JsonConvert.DeserializeObject<RespStatus>(htmlText);
                }
                

                //解析议价返回消息

                //如果议价成功，则返回成功
                if (false)
                {
                    success = true;
                    break;
                }
                    

            }

            return success;
            
        }

        

        public string GetVeriCode(string captchaUrl)
        {
            string page = Util.GetPage(Form1.cartUrl, cc, out ccReturned);
            cc.Add(ccReturned);

            Bitmap image = new Bitmap(Util.GetCheckCodeImageStream(captchaUrl, cc, out ccReturned));
            cc.Add(ccReturned);
            checkCodeForm.checkCodePic.Image = image;
            checkCodeForm.Text = product.prodTypeDesc + " 生成订单";
            checkCodeForm.ShowDialog();
            return checkCodeForm.txtCheckCode.Text;

        }

    }
}
